using MediatR;
using WMS.Domain;
using WMS.ErrorCode;
using WMS.Infrasturcture.Interfaces;
using WMS.WebApiRead.Application.Command;
using WMS.WebApiRead.DTO;

namespace WMS.WebApiRead.Application.Commandhandler
{
    /// <summary>
    /// 处理 <see cref="StoragelocationInfoQueryCommand"/> 库位信息分页查询命令的处理器
    /// </summary>
    public class StoragelocationInfoQueryCommandHandler : IRequestHandler<StoragelocationInfoQueryCommand, ApiResult<ApiPaging<List<StoragelocationInfoResultDTO>>>>
    {
        private readonly IBaseRepository<StoragelocationInfo> storagelocationRepository;
        private readonly IBaseRepository<WarehouseSupervisor> supervisorRepository;

        /// <summary>
        /// 构造函数，注入库位信息仓储和主管仓储
        /// </summary>
        /// <param name="storagelocationRepository">库位信息仓储接口</param>
        /// <param name="supervisorRepository">主管仓储接口</param>
        public StoragelocationInfoQueryCommandHandler(
            IBaseRepository<StoragelocationInfo> storagelocationRepository,
            IBaseRepository<WarehouseSupervisor> supervisorRepository)
        {
            this.storagelocationRepository = storagelocationRepository;
            this.supervisorRepository = supervisorRepository;
        }

        /// <summary>
        /// 处理 <see cref="StoragelocationInfoQueryCommand"/> 库位信息分页查询命令
        /// </summary>
        /// <param name="request">命令请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回分页查询结果</returns>
        public async Task<ApiResult<ApiPaging<List<StoragelocationInfoResultDTO>>>> Handle(StoragelocationInfoQueryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 联表查询：库位信息表 LEFT JOIN 主管表
                var query = from location in storagelocationRepository.GetAll()
                            where !location.IsDeleted // 只查询未删除的记录
                            join supervisor in supervisorRepository.GetAll()
                            on location.SupervisorId equals supervisor.SupervisorId into supervisorGroup
                            from supervisor in supervisorGroup.DefaultIfEmpty()
                            select new
                            {
                                Location = location,
                                SupervisorName = supervisor != null ? supervisor.SupervisorName : "未分配"
                            };

                // 根据库位名称进行模糊查询
                if (!string.IsNullOrWhiteSpace(request.QueryDTO.StoragelocationName))
                {
                    query = query.Where(x => x.Location.StoragelocationName.Contains(request.QueryDTO.StoragelocationName));
                }

                // 根据库位状态进行筛选
                if (request.QueryDTO.StoragelocationState.HasValue)
                {
                    query = query.Where(x => x.Location.StoragelocationState == request.QueryDTO.StoragelocationState.Value);
                }

                // 按排序字段排序
                query = query.OrderBy(x => x.Location.StoragelocationScore).ThenByDescending(x => x.Location.CreateTime);

                // 计算总记录数
                var totalCount = query.Count();

                // 计算总页数
                var totalPage = (int)Math.Ceiling((double)totalCount / request.QueryDTO.PageSize);

                // 执行分页查询并投影到DTO
                var data = query
                    .Skip((request.QueryDTO.PageIndex - 1) * request.QueryDTO.PageSize)
                    .Take(request.QueryDTO.PageSize)
                    .Select(x => new StoragelocationInfoResultDTO
                    {
                        StoragelocationId = x.Location.StoragelocationId,
                        StoragelocationCode = x.Location.StoragelocationCode,
                        StoragelocationName = x.Location.StoragelocationName,
                        StoragelocationCapacity = x.Location.StoragelocationCapacity,
                        StoragelocationState = x.Location.StoragelocationState,
                        StoragelocationContent = x.Location.StoragelocationContent,
                        StoragelocationScore = x.Location.StoragelocationScore,
                        SupervisorId = x.Location.SupervisorId,
                        SupervisorName = x.SupervisorName, // 联表查询得到的主管名称
                        IsDeleted = x.Location.IsDeleted,
                        DataStatus = x.Location.DataStatus, // 数据状态
                        CreateName = x.Location.CreateName,
                        CreateTime = x.Location.CreateTime,
                        UpdateName = x.Location.UpdateName,
                        UpdateTime = x.Location.UpdateTime,
                        DeleteName = x.Location.DeleteName,
                        DeleteTime = x.Location.DeleteTime
                    })
                    .ToList();

                // 返回分页结果
                return new ApiResult<ApiPaging<List<StoragelocationInfoResultDTO>>>
                {
                    Code = ApiResultEnum.查询成功,
                    Message = "查询库位信息成功",
                    Data = new ApiPaging<List<StoragelocationInfoResultDTO>>
                    {
                        TotalCount = totalCount,
                        TotalPage = totalPage,
                        Data = data
                    }
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<ApiPaging<List<StoragelocationInfoResultDTO>>>
                {
                    Code = ApiResultEnum.查询失败,
                    Message = $"查询库位信息异常：{ex.Message}",
                    Data = new ApiPaging<List<StoragelocationInfoResultDTO>>
                    {
                        TotalCount = 0,
                        TotalPage = 0,
                        Data = new List<StoragelocationInfoResultDTO>()
                    }
                };
            }
        }
    }
}

